package com.chinaisafe.gateway.config;

import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.stp.StpUtil;
import com.chinaisafe.base.common.enums.AnswerCodeEnum;
import com.chinaisafe.base.common.vo.Answer;
import com.chinaisafe.gateway.sdk.vo.request.Oauth2ClientLoginReqVo;
import com.chinaisafe.gateway.sdk.vo.response.Oauth2ClientLoginRespVo;
import com.chinaisafe.gateway.server.service.user.IGatewayUserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.Optional;


/**
 * SaOAuth2TemplateImpl
 * Sa-Token OAuth2.0 整合实现
 * @author xuefu.shu
 * @date 2024-07-03 10:42
 */
@Component
public class SaOauth2TemplateImpl extends SaOAuth2Template {

    @Resource
    private IGatewayUserService gatewayTokenService;

    /**
     * 根据 id 获取 Client 信息
     * @param clientId 客户端id
     * @return SaClientModel
     */
    @Override
    public SaClientModel getClientModel(String clientId) {
        Oauth2ClientLoginReqVo clientLoginReqVo = new Oauth2ClientLoginReqVo();
        clientLoginReqVo.setClientId(clientId);
        Answer<Oauth2ClientLoginRespVo> clientInfo = gatewayTokenService.getOauth2LoginClientInfo(clientLoginReqVo);

        if (AnswerCodeEnum.SUCCESS.getCode() == clientInfo.getCode()){
            Oauth2ClientLoginRespVo clientInfoData = clientInfo.getData();

            return new SaClientModel()
                    .setClientId(clientInfoData.getClientId())
                    .setClientSecret(clientInfoData.getClientSecret())
                    .setAllowUrl(clientInfoData.allowUrl)
                    .setContractScope(clientInfoData.getContractScope());
        }
        return null;
    }

    /**
     * 存储授权信息
     * @param clientId 客户端id
     * @param loginId 登录id
     * @param scope 资源授权范围
     */
    @Override
    public void saveGrantScope(String clientId, Object loginId, String scope) {
        super.saveGrantScope(clientId, loginId, scope);
    }

    /**
     * 重写 Access-Token 生成策略：复用登录会话的Token
     * @param clientId 客户端id
     * @param loginId 登录id
     * @param scope 资源授权范围
     * @return String
     */
    @Override
    public String randomAccessToken(String clientId, Object loginId, String scope) {
        String tokenValue = Optional.ofNullable(clientId).map(item->StpUtil.createLoginSession(item)).orElseGet(()->StpUtil.createLoginSession(loginId));
        return tokenValue;
    }

    /**
     * 重写 client-Token 生成策略：复用登录会话的Token
     * @param clientId 客户端id
     * @param scope 资源授权范围
     * @return String
     */
    @Override
    public String randomClientToken(String clientId, String scope) {
        return StpUtil.createLoginSession(clientId);
    }

}
